package vn.com.demand.widget;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.regex.Pattern;

import org.apache.commons.dbutils.ResultSetHandler;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;

import vn.com.demand.util.DpUtils;

public class SearcheableTable extends Composite {

	private Table table;
	private TableViewer tableViewer;
	private MyViewerFilter filter;
	private Text text;
	private ItemBrowserCommand command;
	private TableColumn codeColumn;
	private TableColumn descriptionColumn;
	
	/**
	 * Create the composite
	 * 
	 * @param parent
	 * @param style
	 * @throws SQLException
	 */
	public SearcheableTable(Composite parent, int style, String sql,
			final Text text) throws SQLException {
		super(parent, style);
		setLayout(new FillLayout());

		command = new ItemBrowserCommand(sql, null, new MyModel());
		this.text = text;
		createCompositeContent();
		//
	}
	
	public SearcheableTable(Composite parent, int style, ItemBrowserCommand command,
			final Text text) throws SQLException {
		super(parent, style);
		setLayout(new FillLayout());
		this.command = command;
		this.text = text;
		createCompositeContent();
		//
	}

	private void createCompositeContent()
			throws SQLException {
		tableViewer = new TableViewer(this, getStyle());
		table = tableViewer.getTable();
		table.setLinesVisible(true);
		table.setHeaderVisible(true);
		if (null == codeColumn) {
			codeColumn = new TableColumn(table,
					SWT.NONE);
			codeColumn.setWidth(178);
			codeColumn.setText("Code");
		}
		if (null == descriptionColumn) {
			descriptionColumn = new TableColumn(table,
					SWT.NONE);
			descriptionColumn.setWidth(265);
			descriptionColumn.setText("Description");
		}

		tableViewer
				.addSelectionChangedListener(new ISelectionChangedListener() {

					public void selectionChanged(SelectionChangedEvent event) {
						TableItem[] selection = tableViewer.getTable()
								.getSelection();
						if (null != selection && selection.length > 0) {
							MyModel model = (MyModel) selection[0].getData();
							if (null != text) {
								text.setText(model.code);
							}
						}
					}

				});

		tableViewer.setContentProvider(new MyContentProvider());
		tableViewer.setLabelProvider(new MyLabelProvider());
		tableViewer.setInput(createModel());

		filter = new MyViewerFilter(null);
		tableViewer.setFilters(new ViewerFilter[] { filter });
	}

	private class MyViewerFilter extends ViewerFilter {

		private String filterValue;
		private Pattern codePattern;
		private Pattern descriptionPattern;

		public MyViewerFilter(String filterValue) {
			setFilterValue(filterValue);
		}

		@Override
		public boolean select(Viewer arg0, Object parentElement, Object element) {
			if (null == filterValue) {
				return true;
			}
			MyModel model = (MyModel) element;
			if (codePattern.matcher(model.code).find()
					|| (null != model.description && descriptionPattern
							.matcher(model.description).find())) {
				return true;
			}
			return false;
		}

		public void setFilterValue(String value) {
			filterValue = value;
			codePattern = Pattern.compile(filterValue + ".*",
					Pattern.CASE_INSENSITIVE);
			descriptionPattern = Pattern.compile(".*" + filterValue + ".*",
					Pattern.CASE_INSENSITIVE);
		}
	};

	private class MyContentProvider implements ITreeContentProvider {

		public Object[] getChildren(Object arg0) {
			return null;
		}

		public Object getParent(Object arg0) {
			return null;
		}

		public boolean hasChildren(Object arg0) {
			return false;
		}

		public Object[] getElements(Object myModelArr) {
			return (Object[]) myModelArr;
		}

		public void dispose() {

		}

		public void inputChanged(Viewer arg0, Object arg1, Object arg2) {

		}

	}

	private MyModel[] createModel() throws SQLException {
		return (MyModel[]) command.execute(new MyModel());
	}

	private class MyLabelProvider extends LabelProvider implements
			ITableLabelProvider {

		public Image getColumnImage(Object arg0, int arg1) {
			return null;
		}

		public String getColumnText(Object model, int column) {
			switch (column) {
			case 0:
				return ((MyModel) model).code;
			case 1:
				return ((MyModel) model).description;
			default:
				break;
			}
			return null;
		}

	}

	public class MyModel implements ResultSetHandler {

		String code;
		String description;
		
		public String getCode() {
			return code;
		}

		public String getDescription() {
			return description;
		}

		public Object handle(ResultSet rs) throws SQLException {
			ArrayList<MyModel> list = new ArrayList<MyModel>();
			while (rs.next()) {
				MyModel model = new MyModel();
				model.code = DpUtils.trim(rs.getString(1));
				model.description = DpUtils.trim(rs.getString(2));
				list.add(model);
			}
			return list.toArray(new MyModel[0]);
		}

		@Override
		public String toString() {
			return code + " = " + description;
		}
	}

	@Override
	public void dispose() {
		super.dispose();
	}

	@Override
	protected void checkSubclass() {
		// Disable the check that prevents subclassing of SWT components
	}

	public Object[] getChildren(Object arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	public Object getParent(Object arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	public boolean hasChildren(Object arg0) {
		// TODO Auto-generated method stub
		return false;
	}

	public Object[] getElements(Object arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
		// TODO Auto-generated method stub

	}
	
	public Object getSelectedITem() {
		TableItem[] selection = tableViewer.getTable().getSelection();
		if (selection != null && selection.length > 0) {
			Object element = selection[0].getData();
			return element;
		}
		return null;
	}
	
	public String[] getSelectedItemsCode() {
		TableItem[] selection = tableViewer.getTable().getSelection();
		if (selection != null && selection.length > 0) {
			String[] results = new String[selection.length];
			for (int i = 0; i < selection.length; i++) {
				results[i] = ((MyModel) selection[i].getData()).code;
			}
			return results;
		}
		return null;
	}

	public void setSelectedItem(String value) {

	}

	public void setFilterValue(String value) {
		filter.setFilterValue(value);
		tableViewer.refresh();
	}

	public TableColumn getDescriptionColumn() {
		return descriptionColumn;
	}

	public void setDescriptionColumn(TableColumn descriptionColumn) {
		this.descriptionColumn = descriptionColumn;
	}

	public TableColumn getCodeColumn() {
		return codeColumn;
	}

	public void setCodeColumn(TableColumn codeColumn) {
		this.codeColumn = codeColumn;
	}
}
